/*
 * CopyRright (c) laolema.cn: 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.epfresh.api.utils;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore.Images.ImageColumns;
import android.util.Base64;


import com.epfresh.api.constant.Constant;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * @author WangZhanghuan @date 2015-08-15 22:22:22
 * @version v1.0
 */

public class FileUtil {

    public static String mSdRootPath;
    public static String mDataCacheRootPath;
    public static String mExternalCachePath;
    public static String mAvailableRootPath;
    public static String mAvailableRootWithDecoratePath;
    public static String mPackagePath;
    public static boolean isSdAvailable;
    public static Context context;

    public static void init(Context context) {
        FileUtil.context = context;
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            isSdAvailable = true;
            File externalStorageDirectory = Environment.getExternalStorageDirectory();
            if (externalStorageDirectory != null) {
                mSdRootPath = externalStorageDirectory.getPath();
                if(context.getExternalCacheDir()!=null)
                    mExternalCachePath = context.getExternalCacheDir().getPath();
            }
        }
        mDataCacheRootPath = context.getCacheDir().getPath();
        mPackagePath = "Android/data/" + context.getPackageName();
        mAvailableRootWithDecoratePath = mSdRootPath == null ? mDataCacheRootPath : mSdRootPath + "/" + mPackagePath;
        mAvailableRootPath = mSdRootPath == null ? mDataCacheRootPath : mSdRootPath;
    }

    public static String getImgCacheDir() {
        File f = new File(mAvailableRootWithDecoratePath + "/cache/xBitmapCache");
        if (!f.exists()) {
            f.mkdirs();
        }
        return mAvailableRootWithDecoratePath + "/cache/xBitmapCache";
    }

    public static SharedPreferences getSharedPreferences(String name, int mode) {
        return context.getSharedPreferences(name, mode);
    }

    public static SharedPreferences getSharedPreferences() {
        return context.getSharedPreferences(
                Constant.USER_INFO_FILE_KEY, Activity.MODE_PRIVATE);
    }
    public static SharedPreferences getBugSharedPreferences() {
        return context.getSharedPreferences(
                "bug", Activity.MODE_PRIVATE);
    }


    public static String getSdRootPath() {
        return mSdRootPath;
    }

    public static void setmSdRootPath(String mSdRootPath) {
        FileUtil.mSdRootPath = mSdRootPath;
    }

    public static String getmDataCacheRootPath() {
        return mDataCacheRootPath;
    }

    public static void setmDataCacheRootPath(String mDataCacheRootPath) {
        FileUtil.mDataCacheRootPath = mDataCacheRootPath;
    }

    public static String getmAvailableRootPath() {
        return mAvailableRootPath;
    }

    public static void setmAvailableRootPath(String mAvailableRootPath) {
        FileUtil.mAvailableRootPath = mAvailableRootPath;
    }

    public static void copyFile(File from, File to) {
        try {
            int byteread = 0;
            if (from.exists() && from.isFile() && from.canRead()) {
                InputStream inStream = new FileInputStream(from);
                FileOutputStream fs = new FileOutputStream(to);
                byte[] buffer = new byte[1024];
                while ((byteread = inStream.read(buffer)) != -1) {
                    fs.write(buffer, 0, byteread);
                }
                inStream.close();
                fs.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String readInternal(String fileName) {

        return read(mDataCacheRootPath, fileName);
    }


    public static String read(String fileName) {
        return read(mAvailableRootWithDecoratePath, fileName);
    }

    public static String read(String fileDir, String fileName) {
        try {
            File file = new File(fileDir, fileName);
            BufferedReader br = new BufferedReader(new FileReader(file));
            String readline = "";
            StringBuffer sb = new StringBuffer();
            while ((readline = br.readLine()) != null) {
                sb.append(readline);
            }
            br.close();
            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;

    }

    public static boolean isSdFileExists(String fileName) {
        File file = new File(mAvailableRootWithDecoratePath, fileName);
        return file.exists();
    }

    public static void saveToInternal(String fileName, String content) {
        saveToFile(mDataCacheRootPath, fileName, content);
    }

    public static void saveToSDCard(String fileName, String content) {
        saveToFile(mAvailableRootWithDecoratePath, fileName, content);
    }

    public static void saveToFile(String fileDir, String fileName, String content) {

        FileOutputStream fos = null;

        try {

            // Environment.getExternalStorageDirectory()。获取sd卡的路径
            File file = new File(fileDir, fileName);
            fos = new FileOutputStream(file);

            fos.write(content.getBytes());
        } catch (Exception e) {

            e.printStackTrace();

        } finally {

            try {
                if (fos != null)
                    fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static File fileFromAsset(Context context, String assetName) throws IOException {
        File outFile = new File(mDataCacheRootPath+"/"+assetName);
        if (!outFile.exists()){
            outFile.createNewFile();
        }
        copy(context.getAssets().open(assetName), outFile);
        return outFile;
    }

    public static void copy(InputStream inputStream, File output) throws IOException {
        OutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(output);
            int read = 0;
            byte[] bytes = new byte[1024];
            while ((read = inputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, read);
            }
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } finally {
                if (outputStream != null) {
                    outputStream.close();
                }
            }
        }
    }
    public static void copy(File in, File output) throws IOException {
        OutputStream outputStream = null;
        FileInputStream inputStream = null;
        try {
            inputStream = new FileInputStream(in);
            outputStream = new FileOutputStream(output);
            int read = 0;
            byte[] bytes = new byte[1024];
            while ((read = inputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, read);
            }
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } finally {
                if (outputStream != null) {
                    outputStream.close();
                }
            }
        }
    }

    public static String getRealFilePath(final Context context, final Uri uri) {
        if (null == uri)
            return null;
        final String scheme = uri.getScheme();
        String data = null;
        if (scheme == null)
            data = uri.getPath();
        else if (ContentResolver.SCHEME_FILE.equals(scheme)) {
            data = uri.getPath();
        } else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) {
            Cursor cursor = context.getContentResolver().query(uri, new String[]{ImageColumns.DATA}, null, null,
                    null);
            if (null != cursor) {
                if (cursor.moveToFirst()) {
                    int index = cursor.getColumnIndex(ImageColumns.DATA);
                    if (index > -1) {
                        data = cursor.getString(index);
                    }
                }
                cursor.close();
            }
        }
        return data;
    }

    public static byte[] getBytesFromFile(File f) {
        if (f == null) {
            return null;
        }
        try {
            FileInputStream stream = new FileInputStream(f);
            ByteArrayOutputStream out = new ByteArrayOutputStream(1000);
            byte[] b = new byte[1000];
            int n;
            while ((n = stream.read(b)) != -1)
                out.write(b, 0, n);
            stream.close();
            out.close();
            return out.toByteArray();
        } catch (IOException e) {
        }
        return null;
    }

    public static void delete(File file, boolean isDeleteFileDirectory) {
        if (file != null && file.exists()) {
            if (file.isFile()) {
                file.delete();
                return;
            }

            if (file.isDirectory()) {
                File[] childFiles = file.listFiles();
                if (childFiles == null || childFiles.length == 0) {
                    file.delete();
                    return;
                }

                for (int i = 0; i < childFiles.length; i++) {
                    delete(childFiles[i], true);
                }
                if (isDeleteFileDirectory) {
                    file.delete();
                }
            }
        }
    }

    public static void decodeBase64File(String base64Code, String savePath) throws Exception {
        byte[] buffer = Base64.decode(base64Code, Base64.DEFAULT);
        FileOutputStream out = new FileOutputStream(savePath);
        out.write(buffer);
        out.close();
    }

    public static String encodeBase64File(String path) throws Exception {
        File file = new File(path);
        FileInputStream inputFile = new FileInputStream(file);
        byte[] buffer = new byte[(int) file.length()];
        inputFile.read(buffer);
        inputFile.close();
        return Base64.encodeToString(buffer, Base64.DEFAULT);
    }
    public static String encodeBase64FileByNoWrap(String path) throws Exception {
        File file = new File(path);
        FileInputStream inputFile = new FileInputStream(file);
        byte[] buffer = new byte[(int) file.length()];
        inputFile.read(buffer);
        inputFile.close();
        return Base64.encodeToString(buffer, Base64.NO_WRAP);
    }

    public static String bitmapToBase64(Bitmap bitmap) {
        String result = null;
        ByteArrayOutputStream baos = null;
        try {
            if (bitmap != null) {
                baos = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);

                baos.flush();
                baos.close();

                byte[] bitmapBytes = baos.toByteArray();
                result = Base64.encodeToString(bitmapBytes, Base64.DEFAULT);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (baos != null) {
                    baos.flush();
                    baos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

}
